package com.ton.system.controller.user;

import cn.hutool.crypto.digest.BCrypt;
import com.ton.config.annotation.accessLimit.AccessLimit;
import com.ton.common.entity.SystemUser;
import com.ton.context.RedisContext;
import com.ton.system.dto.LoginDto;
import com.ton.system.dto.R;
import com.ton.system.dto.RegisterDto;
import com.ton.system.dto.ResultCode;
import com.ton.system.entity.User;
import com.ton.system.service.UserService;
import com.ton.utils.auth.AuthUtil;
import com.ton.utils.StringUtil;
import com.ton.system.vo.LoginUserVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.Objects;
import java.util.Optional;

@Api(value = "登陆注册",tags = "登录注册")
@Slf4j
@RestController
public class LoginController {
    @Autowired
    private RedisContext redisContext;

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Autowired
    private UserService userService;

    @Autowired
    private AuthUtil authUtil;
    @ApiOperation(value = "登陆请求",notes = "登录请求")
    @PostMapping("login")
    public R<?> login(@Valid @RequestBody @ApiParam("登陆表单模型") LoginDto loginDto){
         // 日志
        log.info("请求登录：{}", loginDto.getLoginName());
        //System.out.println(loginDto);
        //根据UUID获取验证码
        String uuid=loginDto.getUuid();

        //获取redis中验证码的key
        String key=redisContext.getCaptchaKey(uuid);


        //到redis中获取验证码
        Object value=redisTemplate.opsForValue().get(key);
        value = "1234"; //强制设置验证码
        if(value == null){
            //验证码失效
            return R.error(ResultCode.SYSTEM_CODE_INVALID);
        }

         //消费验证码(从redis中删除)
        redisTemplate.delete(key);

        //获取验证码
        String code=value.toString();

        if (!code.equalsIgnoreCase(loginDto.getCode())){
            //验证码失效
            return R.error(ResultCode.SYSTEM_CODE_ERROR);
        }
        User user = userService.getUserByName(loginDto.getLoginName());

        if(Objects.isNull(user)){
            //用户不存在
            return R.error(ResultCode.ACCOUNT_NOT_EXISTS);
        }

        //验证密码
        //if (BCrypt.hashpw(loginDto.getLoginPwd()).equals(loginUser.getLoginPwd())){
       if(!BCrypt.checkpw(loginDto.getLoginPwd(),user.getPassword())){
        // System.out.println(loginDto.getLoginPwd());
        // System.out.println(BCrypt.hashpw(loginDto.getLoginPwd()));
        // System.out.println(loginUser.getLoginPwd());
            //密码错误
            return R.error(ResultCode.ACCOUNT_INVALID_PWD);

        }
        if(user.getStatus() == null){
           user.setStatus(0);//正常状态
        }
        //状态验证
        if(user.getStatus() == 2){
            //状态错误
            return R.error(ResultCode.ACCOUNT_INVALID);
        }

        LoginUserVo loginUser = new LoginUserVo();
        //
        loginUser.setId(user.getId());
        loginUser.setLoginName(user.getName());
        loginUser.setAvatar(user.getAvatar());
        loginUser.setStatus(user.getStatus());
        loginUser.setAccountType(user.getAccountType()==null?0:user.getAccountType());

        String token= authUtil.createToken(loginUser);
        loginUser.setToken(token);
        loginUser.setLoginPwd(null);//密码不返回
        loginUser.setAccountType(null);//用户类型不返回到前端去
        String date;
        if(Objects.nonNull(user.getExpirationTime())){
            date = new SimpleDateFormat("yyyy-MM-dd").format(user.getExpirationTime());
        }else{
             date ="";
        }
        loginUser.setExpirationTime(date);//设置用户会议过期时间
//        loginUser.setBalance(user.getBalance());//设置用户余额
//        loginUser.setJsUpperLimit(user.getJsUpperLimit());//设置Js限制
//        loginUser.setUrlUpperLimit(user.getUrlUpperLimit());//设置URL限制
        // loginUser.setBalance(user.getBalance());//设置用户余额
        // loginUser.setBalance(user.getBalance());//设置用户余额
        // loginUser.setBalance(user.getBalance());//设置用户余额
        return R.ok(loginUser.getToken());
    }

   @AccessLimit(max = 5) //每分钟最多访问五次
   @ApiOperation(value = "账户注册",notes = "账户注册")
   @PostMapping("register")
   public R<?> register(@Valid @RequestBody @ApiParam("注册表单模型") RegisterDto dto){
//        tokenUtil.removeRedisToken(dto);
        Optional.ofNullable(dto.getLoginPwd()).orElseThrow(()->new RuntimeException("请输入登录密码"));
        Optional.ofNullable(dto.getLoginName()).orElseThrow(()->new RuntimeException("请输入用户名"));
        Optional.ofNullable(dto.getReLoginPwd()).orElseThrow(()->new RuntimeException("请输入确认密码"));
        if(!dto.getLoginPwd().equals(dto.getReLoginPwd())){
          throw new RuntimeException("两次输入密码不一致");
        }

       if (dto.getLoginPwd().length()<6){
           throw new RuntimeException("密码长度不能小于6位");
       }
       User one = userService.getUserByName(dto.getLoginName());
       Optional.ofNullable(one).ifPresent(v->{
          throw new RuntimeException("用户名已存在!");
       });

       User user=new User();
       user.setName(dto.getLoginName());
       //密码加密
       String pwd=BCrypt.hashpw(dto.getLoginPwd());
       user.setPassword(pwd);

       String key = StringUtil.getRandomString(20,0); //生成秘钥
       user.setStrKey(key);

       //设置相关信息
       user.setUserAgent(AuthUtil.getUA()); //设置UA
       user.setIp(AuthUtil.getIp()); //设置IP
       user.setAvatar("https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png"); //设置默认头像
//       user.setExpirationTime(DateUtil.format("2000-01-01 00:00:00",0));//设置过期时间
       user.setStatus(0); //设置状态
       user.setVip(0); //设置是否是VIP
       user.setAdmin(1); //设置是否是管理员
       user.setIsDeleted(0); //设置是否逻辑删除
       user.setCreateUser(0);
       user.setUpdateUser(0);

        // 注入业务逻辑层
       boolean save = userService.saveUser(user);
       if (save) {
        return R.ok("注册成功");
       }
       return  R.error(ResultCode.SYSTEM_REGISTER_ERROR);
   }


   @ApiOperation(value = "退出请求",notes = "退出登录")
   @PostMapping("logout")
   public R<?> logout(@RequestHeader("Authorization") @ApiParam("退出验证模型")  String auth){
        authUtil.removeRedisToken(auth);
        return R.ok();
   }

    @ApiOperation(value = "获取用户请求",notes = "获取用户请求")
    @GetMapping("/user/info")
    //@RequestHeader 获取请求头中指定key的值
    public R<?> getInfo(){
        SystemUser vo = authUtil.loginVOThreadLocal.get();
        if(vo == null){
            return R.error(ResultCode.SYSTEM_TOKEN_INVALID);
        }
        return R.ok(vo);
    }
}

